/*
* Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:  Implementation of the LocationManager.
*               Location manager queries the current location, saves locations to Ovi map
                and sends/receives locations to/from another device.
*
*/

#include "locationmanager.h"
#include <QtCore/QDebug>

#include <QGeoPositionInfoSource>
#include <QLandmarkManager>
#include <QLandmark>
#include <QLandmarkCategoryId>
#include <QLandmarkCategoryFilter>
#include <QGeoPlace>
#include <QGeoCoordinate>

QTM_USE_NAMESPACE

LocationManager::LocationManager( QObject *parent )
: QObject( parent )
{
    qDebug() << "LocationManager::LocationManager : begin";
    m_source = QGeoPositionInfoSource::createDefaultSource( this );
    m_source->setPreferredPositioningMethods( QGeoPositionInfoSource::NonSatellitePositioningMethods );
    connect( m_source, SIGNAL( positionUpdated(QGeoPositionInfo) ), this, SLOT( handlePositionUpdate(QGeoPositionInfo) ) );
    connect( m_source, SIGNAL( updateTimeout() ), this, SLOT( handleUpdateTimeout() ) );

    m_landmarkManager = new QLandmarkManager();

    // Get current position
    startLocationUpdate();
    qDebug() << "LocationManager::LocationManager : end";
}

LocationManager::~LocationManager()
{
    if (m_source) {
        m_source->stopUpdates();
    }
    delete m_source;
}

void LocationManager::startLocationUpdate()
{
    qDebug() << "LocationManager::startLocationUpdate : begin";
    if (m_source) {
        // Start location updates. 10 sec interval.
        m_source->setUpdateInterval( 10000 );
        m_source->startUpdates();
    }
    qDebug() << "LocationManager::startLocationUpdate : end ";
}

void LocationManager::handlePositionUpdate( const QGeoPositionInfo &update )
{
    qDebug() << "LocationManager::handlePositionUpdate : begin" << update.isValid();

    if ( m_source ) {
        m_source->stopUpdates();
    }

    if ( update.isValid() ) {
        m_current = update;
        m_LocationName = "";
        emit positionChanged( true );
        emit locationNameChanged();
    }

    qDebug() << "LocationManager::handlePositionUpdate : end ";
}

void LocationManager::handleUpdateTimeout()
{
    qDebug() << "LocationManager::handleUpdateTimeout : begin";
    qDebug() << "LocationManager::handleUpdateTimeout : end ";
}

double LocationManager::latitude() const
{
    return m_current.coordinate().latitude();
}

double LocationManager::longitude() const
{
    return m_current.coordinate().longitude();
}

QString LocationManager::locationName() const
{
    qDebug() << "LocationManager::locationName : begin";
    qDebug() << "LocationManager::locationName : end";
    if ( m_LocationName.isEmpty() ) {
        return m_current.coordinate().toString( QGeoCoordinate::DegreesMinutesSecondsWithHemisphere );
    }
    return m_LocationName;
}

void LocationManager::setLocationName( const QString &name )
{
    qDebug() << "LocationManager::setLocationName : begin " << name;
    m_LocationName = name;
    emit locationNameChanged();
    qDebug() << "LocationManager::setLocationName : end";
}

void LocationManager::storeCurrentLocation( const QString &name )
{
    qDebug() << "LocationManager::storeCurrentLocation : begin " << name;

    QLandmark landmark;
    landmark.setName( name );
    landmark.setCoordinate( m_current.coordinate() );

    bool success = m_landmarkManager->saveLandmark( &landmark );
    if ( success ) {
        setLocationName( name );
    }
    qDebug() << "LocationManager::storeCurrentLocation : end " << success;
}

void LocationManager::shareCurrentLocation( const QString &name, double latitude, double longitude )
{
    qDebug() << "LocationManager::shareCurrentLocation : begin";

    qDebug() << "Location name : " << name;
    qDebug() << "Location latitude : " << latitude;
    qDebug() << "Location longitude : " << longitude;

    QByteArray array;
    array.append( name.length() );
    array.append( name.toUtf8() );

    QByteArray latitudeArray;
    QByteArray temp = latitudeArray.number( latitude );

    array.append( temp.length() );
    array.append( temp );

    QByteArray longitudeArray;
    temp = longitudeArray.number( longitude );
    array.append( temp.length() );
    array.append( temp );
    emit sendLocation( array );
    qDebug() << "LocationManager::shareCurrentLocation : end";
}

void LocationManager::receiveLocation( const QByteArray &data )
{
    qDebug() << "LocationManager::receiveLocation : begin";
    int index = 0;
    int dataLength = data.at( index );
    index++;

    QByteArray name = data.mid( index, dataLength );
    QString locationName( name );

    index += dataLength;
    dataLength = data.at( index );
    index++;
    QByteArray temp1 = data.mid( index, dataLength );
    double latitude = temp1.toDouble();

    index += dataLength;
    dataLength = data.at( index );
    index++;

    QByteArray temp2 = data.mid( index, dataLength );
    double longitude = temp2.toDouble();

    QLandmark landmark;
    landmark.setName( locationName );
    QGeoCoordinate coord( latitude, longitude );
    landmark.setCoordinate( coord );

    qDebug() << "Location name : " << locationName;
    qDebug() << "Location latitude : " << latitude;
    qDebug() << "Location longitude : " << longitude;

    bool success = m_landmarkManager->saveLandmark( &landmark );
    if ( success ) {
        m_current.setCoordinate( coord );
        setLocationName( locationName );
        emit positionChanged( false );
        emit locationReceived( locationName );
    }
    qDebug() << "LocationManager::receiveLocation : end";
}
